package com.exchange.controller;

import com.exchange.dto.ExchangeCodeDto;
import com.exchange.entity.ExchangeCode;
import com.exchange.service.ExchangeCodeService;
import com.exchange.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/exchange-codes")
@CrossOrigin(origins = "*")
@PreAuthorize("hasRole('MERCHANT') or hasRole('ADMIN')")
public class ExchangeCodeController {
    
    @Autowired
    private ExchangeCodeService exchangeCodeService;
    
    @GetMapping
    public ResponseEntity<List<ExchangeCodeDto>> getExchangeCodesByMerchant() {
        // Get the current user's ID from the security context
        Long currentUserId = SecurityUtils.getCurrentUserId();
        
        // In a real application, we would get the merchant ID from the user profile
        // For now, using a placeholder based on user ID
        Long currentMerchantId = currentUserId; // This would be looked up in a real app
        
        List<ExchangeCodeDto> codes = exchangeCodeService.findByMerchantId(currentMerchantId);
        return ResponseEntity.ok(codes);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<ExchangeCodeDto> getExchangeCodeById(@PathVariable Long id) {
        var result = exchangeCodeService.findById(id);
        if (result.isPresent()) {
            return ResponseEntity.ok(result.get());
        } else {
            return ResponseEntity.notFound().build();
        }
    }
    
    @PostMapping
    public ResponseEntity<ExchangeCodeDto> createExchangeCode(@RequestBody ExchangeCode exchangeCode) {
        // Get the current user's ID from the security context
        Long currentUserId = SecurityUtils.getCurrentUserId();
        
        // In a real application, we would get the merchant ID from the user profile
        // For now, using a placeholder based on user ID
        Long currentMerchantId = currentUserId; // This would be looked up in a real app
        
        ExchangeCodeDto createdCode = exchangeCodeService.createExchangeCode(exchangeCode, currentMerchantId);
        return ResponseEntity.ok(createdCode);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<ExchangeCodeDto> updateExchangeCode(@PathVariable Long id, @RequestBody ExchangeCode exchangeCode) {
        ExchangeCodeDto result = exchangeCodeService.updateExchangeCode(id, exchangeCode);
        if (result != null) {
            return ResponseEntity.ok(result);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteExchangeCode(@PathVariable Long id) {
        boolean deleted = exchangeCodeService.deleteExchangeCode(id);
        return deleted ? ResponseEntity.ok().build() : ResponseEntity.notFound().build();
    }
    
    // API for customers to use exchange codes
    @PostMapping("/use")
    @PreAuthorize("permitAll")  // Allow any user to use an exchange code
    public ResponseEntity<?> useExchangeCode(@RequestBody UseCodeRequest request) {
        Object result = exchangeCodeService.useExchangeCode(request.getCode(), request.getPassword());
        return ResponseEntity.ok(result);
    }
    
    // Endpoint for merchants to generate batch exchange codes
    @PostMapping("/batch-generate")
    public ResponseEntity<List<ExchangeCodeDto>> generateBatchExchangeCodes(@RequestBody BatchGenerationRequest request) {
        // Get the current user's ID from the security context
        Long currentUserId = SecurityUtils.getCurrentUserId();
        
        // In a real application, we would get the merchant ID from the user profile
        // For now, using a placeholder based on user ID
        Long currentMerchantId = currentUserId; // This would be looked up in a real app
        
        List<ExchangeCodeDto> generatedCodes = exchangeCodeService.generateBatchExchangeCodes(
            request.getCount(), 
            currentMerchantId, 
            request.getExpirationDate()
        );
        return ResponseEntity.ok(generatedCodes);
    }
    
    public static class UseCodeRequest {
        private String code;
        private String password; // Optional password for additional security
        
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }
    
    public static class BatchGenerationRequest {
        private int count;
        private java.time.LocalDate expirationDate;
        
        public int getCount() { return count; }
        public void setCount(int count) { this.count = count; }
        
        public java.time.LocalDate getExpirationDate() { return expirationDate; }
        public void setExpirationDate(java.time.LocalDate expirationDate) { this.expirationDate = expirationDate; }
    }
}